package com.ocom.webapi.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.constant.WebApiServiceUrl;
import com.ocom.common.entity.human.EntityDeptInfo;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.*;
import com.ocom.redis.util.RedisUtil;
import com.ocom.security.authentication.YoCiUser;
import com.ocom.security.utils.SecurityUtils;
import com.ocom.webapi.feign.HumanClientService;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

import static cn.hutool.poi.excel.cell.CellUtil.getCellValue;

@RestController
@PreAuthorize("@pms.hasRole('ROLE_WEB')" )
public class DeptController {

    @Resource
    private RedisUtil redisUtil;

    @Autowired
    private HumanClientService humanClientService;
    /**
     *@Description:部门批量导入(deptList/import)
     * @author lu 
     * @param comId
     * @param file
     * @return com.ocom.common.resp.Result
     * @date 2023/2/14 13:45       
     */
    @PostMapping(WebApiServiceUrl.Url_DeptListImport)
    public Result deptListImport(Long comId, @RequestPart("file") MultipartFile file){
        YoCiUser yoCiUser= SecurityUtils.getYoCiUser();
        comId = yoCiUser.getComId();
        Long timestamp = System.currentTimeMillis();
        Map<String,Object> map1=new HashMap<>();
        map1.put("key","ImportErr:detail:"+comId+":"+timestamp);
        map1.put("type",5);
        map1.put("name","部门批量导入");
        map1.put("timestamp",timestamp);
        map1.put("datetime", DateUtil.getDateTime());
        redisUtil.leftPush("ImportErr:"+comId,map1,86400L);

        List<String> list=new ArrayList<>();
        Workbook workbook = null ;
        String fileName = file.getOriginalFilename();
        if(fileName.endsWith("xls")){
            //2003
            try {
                workbook = new HSSFWorkbook(file.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if(fileName.endsWith("xlsx")){
            //2007
            try {
                workbook = new XSSFWorkbook(file.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
            try {
                throw new Exception("文件不是Excel文件");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        Sheet sheet = workbook.getSheetAt(0);
        int rows = sheet.getLastRowNum();// 指的行数，一共有多少行+
        if(rows==0){
            try {
                throw new Exception("请填写数据");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //最大层数
        int maxlevel = 0 ;

        int errCount = 0;
        BREAKOFF:
        for (int i = 1; i < rows+1; i++) {
            if(i>5005){
                break BREAKOFF;
            }
            // 读取左端单元格
            Row row = sheet.getRow(i);
            if (row != null) {
                String deptName = JSON.toJSONString(getCellValue(row.getCell(0))).replace("\"", "").replace("\\t", "");
                if(!CommonUtil.isNull(deptName)){
                    errCount = 0;
                    int lev = StringUtil.findStrCount(deptName,"/",0);
                    if(lev== 0)  continue;
                    list.add(deptName);
                    //获取最大层级
                    if(lev>maxlevel){
                        maxlevel = lev;
                    }
                }else{
                    errCount++;
                    if(errCount>10){
                        break BREAKOFF;
                    }
                }
            }
        }

        if(list.size()<=0){
            return ResultUtil.error(ResultEnum.Err_3023);
        }

        //多层级数据结构
        List<List<String>>  listList =new ArrayList<>();
        for (int i = 0;i<maxlevel;i++){
            listList.add(new ArrayList<>());
        }

        //丢入数据
        for (String str:list){
            int lev2 = StringUtil.findStrCount(str,"/",0);
            listList.get(lev2-1).add(str);
        }

        Integer countErr =  0 ;
        //一级一级处理
        for (List<String>  list1:listList){
            if(list1.size()<=0){
                continue;
            }
            Result result = humanClientService.getDeptList(comId,null,1);
            List<EntityDeptInfo> entityDeptInfos = JSON.parseArray(JSON.toJSONString(result.getData()),EntityDeptInfo.class);

            List<EntityDeptInfo> addEntityDeptInfos=new ArrayList<>();

            for (String deptName : list1){

                String[]  deptNameSplit  = deptName.split("/");
                Long parentDeptId  = getParentDept(deptNameSplit,entityDeptInfos);
                if(parentDeptId==null){
                    //上级不存在
                    Map<String,Object> map3=new HashMap<>();
                    map3.put("errMsg","上级部门不存在");
                    map3.put("json", deptName);
                    redisUtil.leftPush("ImportErr:detail:"+comId+":"+timestamp,map3,86400L);
                    countErr++;
                    continue;
                }

                //移除空格
                String ndeptName =  deptNameSplit[deptNameSplit.length-1];
                ndeptName= StringUtils.trimStart(ndeptName," ");
                ndeptName= StringUtils.trimEnd(ndeptName," ");

                EntityDeptInfo entityDeptInfo=new EntityDeptInfo();
                entityDeptInfo.setComId(comId);
                //获取编号的最大值
                Long maxAge01 = entityDeptInfos.stream().max(Comparator.comparing(EntityDeptInfo::getDeptNo)).get().getDeptNo();
                entityDeptInfo.setDeptNo(maxAge01+1);
                entityDeptInfo.setDeptName(ndeptName);
                entityDeptInfo.setGrade(new Integer(deptNameSplit.length).longValue());
                entityDeptInfo.setParentDeptId(parentDeptId);
                entityDeptInfo.setRemark("部门导入");
                Date date=new Date();
                entityDeptInfo.setCreateTime(date);
                entityDeptInfo.setUpdateTime(date);
                addEntityDeptInfos.add(entityDeptInfo);
            }

            JSONObject jsonObject=new JSONObject();
            jsonObject.put("comId",comId);
            jsonObject.put("list",addEntityDeptInfos);
            humanClientService.departmentAddDepts(jsonObject);
        }


//        Map<Integer,String> map=new HashMap<>();
//        //2.按/ 数量多少获取到多个list 存到map
//        for (String s : list) {
//            String[] arr=s.split("/");
//            int arrLength=arr.length;
//
//            if (map.get(arrLength)==null){
//                map.put(arrLength,s);
//            }else{
//                map.put(arrLength,map.get(arrLength)+","+s);
//            }
//        }
//        int countErr=0;
//        //3.map中从小到大开始取出list
//        for(Map.Entry<Integer, String> entry:map.entrySet()){
//            System.out.println(entry.getKey()+"："+entry.getValue());
//            if (entry.getKey()!=1){
//                String pName =entry.getValue();
//                String[] pNameArr=pName.split(",");
//                countErr=countErr+eqPName(comId,pNameArr,timestamp);
//            }
//        }


        Map<String,Integer> mapV=new HashMap<>();
        mapV.put("countErr",countErr);
        return ResultUtil.success(mapV);
    }


    //获取顶级部门Id
    public Long getParentDept(String[] deptNameSplit,List<EntityDeptInfo> entityDeptInfos) {

        Long realDeptId = 0l;

        Boolean  flag = false;


        for (int i=0;i<deptNameSplit.length;i++) {
            if( i+1 == deptNameSplit.length){
                return realDeptId;
            }
            String ndeptName = deptNameSplit[i];
            //单位名称不作判断
            if(!flag){
                flag=true;
                continue;
            }
            ndeptName= StringUtils.trimStart(ndeptName," ");
            ndeptName= StringUtils.trimEnd(ndeptName," ");
            Boolean exist = false;
            for (EntityDeptInfo entityDeptInfo : entityDeptInfos) {
                //匹配到名称
                String ndeptName1= entityDeptInfo.getDeptName();
                ndeptName1= StringUtils.trimStart(ndeptName1," ");
                ndeptName1= StringUtils.trimEnd(ndeptName1," ");
                if (ndeptName1.equals(ndeptName) &&
                        entityDeptInfo.getParentDeptId().equals(realDeptId)) {
                    exist = true;
                    realDeptId = entityDeptInfo.getDeptId();
                    break;
                }
            }
            if (!exist) {
                return null;
            }
        }
        return realDeptId;
    }

    private Integer  eqPName(Long comId,String[] pNameArr,Long timestamp){
        List<String> buEntityDeptInfos=new ArrayList<>();
        int countErr=0;
        for (int i = 0; i < pNameArr.length; i++) {
            String[] pNameLike=pNameArr[i].split("/");
            for (int j = 0; j < pNameLike.length; j++) {
                Result result = humanClientService.getDeptList(comId,null,1);
                if (result.getCode()==200){
                    List<EntityDeptInfo> entityDeptInfos = JSON.parseArray(JSON.toJSONString(result.getData()),EntityDeptInfo.class);
                    boolean exist=false;
                    boolean exists=true;
                    long parentDeptId=0L;
                    for (EntityDeptInfo entityDeptInfo : entityDeptInfos) {
                        if (j==0){
                            if (entityDeptInfo.getDeptId()==0){
                                if (!pNameLike[j].equals(entityDeptInfo.getDeptName())){
                                    exists=false;
                                    countErr=countErr+1;
                                    break;
                                }
                            }
                        } else {
                            //上级部门不存在不处理
                            if (pNameLike[j-1].equals(entityDeptInfo.getDeptName())){
                                //存在上级
                                exist=true;
                                parentDeptId=entityDeptInfo.getDeptId();
                                break;
                            }
                        }
                    }
                    if (exists){
                        if (j!=0){
                            if (exist){
                                exist=false;
                                //存在本级不处理
                                for (EntityDeptInfo entityDeptInfo : entityDeptInfos) {
                                    if (pNameLike[j].equals(entityDeptInfo.getDeptName())){
                                        //存在本级
                                        exist=true;
                                        break;
                                    }
                                }
                                if (!exist){
                                    if (j==pNameLike.length-1){
                                        List<EntityDeptInfo> addEntityDeptInfos=new ArrayList<>();
                                        EntityDeptInfo entityDeptInfo=new EntityDeptInfo();
                                        entityDeptInfo.setComId(comId);
                                        //获取编号的最大值
                                        Long maxAge01 = entityDeptInfos.stream().max(Comparator.comparing(EntityDeptInfo::getDeptNo)).get().getDeptNo();
                                        entityDeptInfo.setDeptNo(maxAge01+1);
                                        entityDeptInfo.setDeptName(pNameLike[j]);
                                        entityDeptInfo.setGrade(Long.valueOf(j));
                                        entityDeptInfo.setParentDeptId(parentDeptId);
                                        entityDeptInfo.setRemark("部门导入");
                                        Date date=new Date();
                                        entityDeptInfo.setCreateTime(date);
                                        entityDeptInfo.setUpdateTime(date);
                                        addEntityDeptInfos.add(entityDeptInfo);
                                        JSONObject jsonObject=new JSONObject();
                                        jsonObject.put("comId",comId);
                                        jsonObject.put("list",addEntityDeptInfos);
                                        Result result1=humanClientService.departmentAddDepts(jsonObject);
                                        if (result1.getCode()!=200){
                                            countErr=countErr+1;
                                        }
                                    }else {
                                        countErr=countErr+1;
                                        buEntityDeptInfos.add(pNameLike[j]);
                                    }

                                }
                            }else {
                                countErr=countErr+1;
                                buEntityDeptInfos.add(pNameLike[j]);
                            }
                        }
                    }else {
                        Map<String,Object> map3=new HashMap<>();
                        map3.put("errMsg","缺少本单位名称");
                        map3.put("json", pNameArr[i]);
                        redisUtil.leftPush("ImportErr:detail:"+comId+":"+timestamp,map3,86400L);
                        break;
                    }
                }

            }
            if (buEntityDeptInfos.size()>0){
                //上级不存在
                Map<String,Object> map3=new HashMap<>();
                map3.put("errMsg","上级部门不存在");
                map3.put("json", JSON.toJSONString(buEntityDeptInfos));
                redisUtil.leftPush("ImportErr:detail:"+comId+":"+timestamp,map3,86400L);
            }
        }
        return countErr;
    }
}
